using System;
using System.Xml.Serialization;

using Microsoft.Xna.Framework;

namespace ProjectTogepi
{
	/// <summary>
	/// Basic element for ships
	/// </summary>
	[Serializable]
	public class Part
	{
		/// <summary>
		/// Trasformation matrix for relative to absolute
		/// </summary>
		/// <remarks>Treat this as read-only plz</remarks>
		[XmlIgnore]
		public Matrix Translation = Matrix.Identity;

		bool updated = false;

		Vector2 position = Vector2.Zero;
		/// <summary>
		/// Position of part
		/// </summary>
		public Vector2 Position
		{
			get { return position; }
			set
			{
				position = value;
				Translation.M41 = position.X;
				Translation.M42 = position.Y;

				updated = false;
			}
		}

		public float rotation = 0;
		/// <summary>
		/// Rotation(in radients)
		/// </summary>
		public float Rotation
		{
			get { return rotation; }
			set
			{
				rotation = value;
				//Rotation along the Z axis
				float cos = (float)Math.Cos(rotation);
				float sin = (float)Math.Sin(rotation);
				Translation.M11 = cos;
				Translation.M12 = sin;
				Translation.M21 = -sin;
				Translation.M22 = cos;

				updated = false;
			}
		}
		/// <summary>
		/// Array of convex sub-parts
		/// </summary>
		public Shape[] Shapes;

		/// <summary>
		/// Updates all AbsoluteVertices
		/// </summary>
		public unsafe void UpdateAbsolute()
		{
			Shape shp;

			if (!updated)
			{
				for (int ii = 0; ii < Shapes.Length; ++ii)
				{
					shp = Shapes[ii];
					if (shp.AbsoluteVertices == null)
						shp.AbsoluteVertices = new Vector2[shp.Vertices.Length];

					fixed (Vector2* verArr = shp.Vertices)
					{
						Vector2* verPtr = verArr;
						fixed (Vector2* absArr = shp.AbsoluteVertices)
						{
							Vector2* absPtr = absArr;

							for (int jj = 0; jj < shp.Vertices.Length; ++jj, ++verPtr, ++absPtr)
							{
								#region INLINE: *absPtr = Vector2.Transform(*verPtr, Translation);

								absPtr->X = ((verPtr->X * Translation.M11) + (verPtr->Y * Translation.M21)) + Translation.M41;
								absPtr->Y = ((verPtr->X * Translation.M12) + (verPtr->Y * Translation.M22)) + Translation.M42;

								#endregion
							}
						}
					}

				}

				updated = true;
			}
		}

		/// <summary>
		/// Convex sub-parts
		/// </summary>
		//TODO: Add hidden edges
		//TODO: Add color
		public class Shape
		{
			/// <summary>
			/// Vertices relative to the part's center
			/// </summary>
			public Vector2[] Vertices;

			/// <summary>
			/// Vertecies tranformed to screen space
			/// </summary>
			[XmlIgnore]
			public Vector2[] AbsoluteVertices = null;
		}
	}
}
